//创建用户的仓库
import { defineStore } from "pinia";
import { reqLogin, reqUserInfo, reqLogout } from "@/api/user";
import { reqFindpermissions } from "@/api/acl/user";
import { reqFindNavTree } from "@/api/acl/menu";
import type {
  ILoginForm,
  ILoginResponseData,
  IUserResponseData,
  ILogoutResponseData,
} from "@/api/user/type";
import type { IUserState } from "@/store/modules/types";
import {
  SET_TOKEN,
  GET_TOKEN,
  REMOVE_TOKEN,
  SET_NAME,
  GET_NAME,
  REMOVE_NAME,
} from "@/utlis/token";
import { constantRoute, anyRoute } from "@/router/routes";
const modules = import.meta.glob("../../views/**/**/index.vue");
import router from "@/router";
const useUserStore = defineStore("User", {
  state: (): IUserState => {
    return {
      token: GET_TOKEN(), //用户唯一标识token
      menuRoutes: constantRoute, //仓库存储菜单需要的数组
      username: "",
      avatar: "",
      name: GET_NAME(),
      perms: [], // 用户权限标识集合
    };
  },
  //异步|逻辑的地方
  actions: {
    //用户登录
    async userLogin(data: ILoginForm) {
      const res: ILoginResponseData = await reqLogin(data);
      if (res.code == 200) {
        this.token = res.data.token as string;
        this.name = res.data.name as string;
        //本地存储持久化
        SET_TOKEN(res.data.token as string);
        SET_NAME(res.data.name as string);
        return "登录成功";
      } else {
        return Promise.reject(new Error(res.msg));
      }
    },
    //获取用户信息方法
    async userInfo() {
      const name = this.name;
      const res: IUserResponseData = await reqUserInfo(name as string);
      if (res.code == 200) {
        this.username = res.data.name;
        this.avatar = res.data.avatar;
        const userAsyncRoute = await reqFindNavTree({
          userName: name as string,
        });
        // 保存用户权限标识集合
        const findPermissions = await reqFindpermissions(name as string);
        this.perms = findPermissions.data;
        // 添加动态路由
        const dynamicRoutes = filterAsyncRoutes(userAsyncRoute.data);
        this.menuRoutes = [...constantRoute, ...dynamicRoutes, anyRoute];
        [...dynamicRoutes, anyRoute].forEach((route: any) => {
          router.addRoute(route);
        });
        return "ok";
      } else {
        return Promise.reject("获取用户信息失败");
      }
    },
    //退出登录
    async userLogout() {
      const res: ILogoutResponseData = await reqLogout();
      if (res.code == 200) {
        this.token = "";
        this.username = "";
        this.avatar = "";
        REMOVE_TOKEN();
        REMOVE_NAME();
        return "ok";
      } else {
        return Promise.reject(new Error(res.msg));
      }
    },
  },
  getters: {},
});

function countSlashes(str: any) {
  // 使用 split 方法按斜杠分割字符串
  const parts = str.split("/");
  // 斜杠的数量等于分割后的数组长度减一
  const slashCount = parts.length - 1;
  return slashCount;
}
const getDynamicComponent = (path: string): any => {
  const component = modules[`../../views${path}/index.vue`];
  if (!component) {
    console.error("component error", path);
  }
  return component;
};
/**
 * 添加动态(菜单)路由
 * @param {*} menuList 菜单列表
 * @param {*} routes 递归创建的动态(菜单)路由
 */
const filterAsyncRoutes = (menuList = [] as any, routes = [] as any) => {
  const processMenuItem = (item: any) => {
    const { url, name, icon, children } = item;
    let component = null;
    if (url) {
      try {
        // console.log(url, countSlashes(url));
        if (countSlashes(url) == 1 && children && children.length > 0) {
          component = () => import("@/layout/index.vue");
        } else {
          component = getDynamicComponent(url);
        }
      } catch (e) {
        console.error(`Failed to load component for URL: ${url}`, e);
      }
    }
    const route = {
      path: url,
      component,
      name,
      meta: {
        title: name,
        icon,
        hidden: false,
      },
    } as any;
    if (children && children.length > 0) {
      route.children = children.flatMap(processMenuItem);
    }
    return route;
  };
  const asyncRoutes = menuList.flatMap(processMenuItem);
  routes.push(...asyncRoutes);
  return routes;
};

//对外暴露获取小仓库
export default useUserStore;
